#include "protocol.hpp"
#include "Socket.hpp"
#include <ctime>
#include <cassert>

void Usage(const std::string &proc)
{
    std::cout << "\r\n Usage: " << proc << " Serverip Serverport" << std::endl;
}

int main(int argc, char *argv[])
{
    // ./ClientCal Serverip Serverport
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(0);
    }

    uint16_t Serverport = std::stoi(argv[2]);
    std::string Serverip = argv[1];

    Sock sk;
    sk.Socket();
    bool r = sk.Connect(Serverport, Serverip);
    if (!r)
        std::cerr << "connect fail..." << std::endl;

    srand(time(nullptr) ^ getpid());
    const std::string oper = "+-*/%=(";

    // 同一类型
    int cnt = 10;
    while (cnt)
    {
        std::cout << "=============" << "剩余测试次数：" << cnt << "=============" << std::endl;
        char op = oper[rand() % oper.size()];
        int x = rand() % 100 + 1;
        int y = rand() % 100;

        std::string inbuffer_stream;

        // std::cout << x << " " << y << std::endl;
        Request req(x, y, op);
        std::string package;
        // 向服务端发送数据
        // 1.序列化
        r = req.serialize(&package);
        if (!r)
        {
            std::cerr << "serialize fail..." << std::endl;
            assert(r);
        }

        // std::cout << "serialize success!!!" << std::endl;

        // 2. 添加报头
        std::string content;
        content = Encode(package);

        // std::cout << content << std::endl;
        // std::cout << "Encode success!!!" << std::endl;

        // 向服务器发送数据
        write(sk.fd(), content.c_str(), content.size());

        std::cout << "write success..." << std::endl;

        // 接收缓冲区
        char inbuffer[1024];
        ssize_t n = read(sk.fd(), inbuffer, sizeof(inbuffer) - 1);

        std::cout << "read success..." << std::endl;

        if (n > 0)
        {
            inbuffer[n] = 0;
            inbuffer_stream += inbuffer;

            // 去报头
            std::string content;
            r = Decode(inbuffer_stream, &content);
            assert(r);
            // 反序列化
            Response rsp(0, 0);
            r = rsp.Deserialize(content);
            assert(r);

            // 打印结果
            rsp.Printret();
            std::cout << "=========================================" << std::endl;
            cnt--;
        }
        sleep(1);
    }
    sk.Close();
}